/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package persistencia.dao;

import interfaces.DAO;
import java.io.PrintWriter;
import java.util.List;
import javax.swing.JOptionPane;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import persistencia.objetos.Usuarios;
import persistencia.utils.hibernateSessionFactory_bd_resti;
import utils.Mensagen;

/**
 *
 * @author Milton
 */
public class AbstractDAO implements DAO {

    protected Session sessao;
    protected Transaction transacao = null;

    /**
     * Inicializa a sessao para efetuar as transacoes no banco de dados
     */
    @Override
    public final void inicializaSessao() {
        this.sessao = hibernateSessionFactory_bd_resti.getSession();
    }

    /**
     * Cadastra um unico objeto no banco de dados
     * @param obj - Objetto a ser cadastrado
     * @return - @true se o objeto foi cadastrado, @false se o objeto nao foi cadastrado
     */
    @Override
    public boolean cadastrar(Object obj) {
        try {

            inicializaSessao();
            this.transacao = sessao.beginTransaction();
            this.sessao.save(obj);

            this.transacao.commit();
            this.sessao.close();

            return true;

        } catch (Exception er) {
            JOptionPane.showMessageDialog(null, er.toString());
            this.sessao.flush();
            this.transacao.rollback();
            this.sessao.close();

            return false;
        }
    }

    /**
     * Altera um unico objeto no banco de dados
     * @param obj - Objetto a ser alterado
     * @return - @true se o objeto foi alterado, @false se o objeto nao foi alterado
     */
    @Override
    public boolean alterar(Object obj) {
        try {

            this.inicializaSessao();
            this.transacao = sessao.beginTransaction();
            this.sessao.update(obj);
            this.transacao.commit();
            this.sessao.close();

            return true;

        } catch (Exception er) {

            this.transacao.rollback();
            this.sessao.close();

            return false;

        }
    }

    /**
     * Exclui um unico objeto no banco de dados
     * @param obj - Objeto a ser excluido
     * @return  - @true se o objeto foi excluido, @false se o objeto nao foi excluido
     */
    @Override
    public boolean excluir(Object obj) {
        try {

            this.inicializaSessao();
            this.transacao = sessao.beginTransaction();
            this.sessao.delete(obj);
            this.transacao.commit();
            this.sessao.close();

            return true;

        } catch (HibernateException er) {
            er.printStackTrace();
            this.transacao.rollback();
            this.sessao.close();

            return false;

        }
    }

    public boolean excluir(String nomeObjeto, String nomeId, int id) {
        String str = nomeId + "=" + id;
        List list = this.consultar(nomeObjeto, str);

        if (this.excluir(list.get(0))) {
            return true;
        }
        return false;

    }

    /**
     * Consulta todos as instancias de um determinado objeto
     * @param nomeObjeto - Nome dos objetos a serem consultados no banco de dados
     * @return - Lista preenchida com as instancias do objeto no banco de dados, @null caso exista alguma excecao
     */
    @Override
    public List listar(String nomeObjeto) {
        try {

            this.inicializaSessao();
            this.transacao = sessao.beginTransaction();
            List list = sessao.createQuery("from " + nomeObjeto).list();
            this.sessao.close();

            return list;

        } catch (HibernateException er) {
            this.transacao.rollback();
            this.sessao.close();
            return null;
        }
    }

    /**
     * Consulta um tipo de objetos do banco de dados a partir de uma determinada condicao
     * @param nomeObjeto - Nome dos objetos a serem consultados no banco de dados
     * @param condicao - Condicao a ser satisfeita para realizar a consulta
     * @return - Lista preenchida com os objetos que satisfazem a condicao
     */
    @Override
    public List consultar(String nomeObjeto, String condicao) {

        this.inicializaSessao();
        this.transacao = sessao.beginTransaction();
        List list = sessao.createQuery("from " + nomeObjeto + " where " + condicao).list();
        this.sessao.close();

        return list;
    }

    public int getMaxID(String nomeTabela, String nomeId) {

        this.inicializaSessao();
        Object obj = sessao.createSQLQuery("SELECT MAX(" + nomeId + ") FROM " + nomeTabela).uniqueResult();
        if (obj == null) {
            return 0;
        }
        return Integer.parseInt(obj.toString());
    }
}
